package com.ml.admin.service.impl;



import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ml.admin.converter.LoginConverter;
import com.ml.admin.mapper.LoginMapper;
import com.ml.admin.pojo.po.UserPO;
import com.ml.admin.pojo.vo.UserVO;
import com.ml.admin.service.LoginService;
import com.ml.admin.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import java.util.Date;

/**
 * @author ml
 * @date 2023/2/24 14:01
 */
@Service
@Slf4j
public class LoginServiceImpl extends ServiceImpl<LoginMapper, UserPO> implements LoginService {
    @Autowired
    private LoginMapper loginMapper;
    @Resource
    private LoginConverter loginConverter;
    //第一版简单设置
    @Value("${password.salt}")
    private String salt;
    @Autowired
    RedisService redisService;
    @Autowired
    MailUtil mailUtil;

    /**
     * 获取邮箱验证码
     * @param email,type 邮箱,1:注册 2：忘记密码
     * @return 成功 or 失败
     */
    @Override
    public ReturnResponse getMailCode(String email,String type) {
        final String two = "2";
        if (StringUtils.isAnyBlank(email,type)){
            return ReturnResponse.failure(ResponseEnum.PARAM_NOT_COMPLETE);
        }
        if (two.equals(type)){
            UserPO userInfo = loginMapper.selectOne(new LambdaQueryWrapper<UserPO>()
                    .eq(UserPO::getEmail, email));
            if (ObjectUtils.isEmpty(userInfo)){
                return ReturnResponse.failure(ResponseEnum.USER_IS_NOT_EXSIT);
            }
        }
        if (!mailUtil.isEmail(email)) {
            return ReturnResponse.failure(ResponseEnum.EMAIL_IS_ERROR);
        }
        String code = mailUtil.CreateCode();
        boolean sendMail = mailUtil.sendMail(email, code);
        if (!sendMail){
            return ReturnResponse.failure("验证码发送失败");
        }
        //设置3min验证码缓存
        redisService.setString(CommonConstant.MAIL_CODE+email,code,3*60L);
        return ReturnResponse.success("发送成功");
    }

    /**
     * 手机号注册
     * @param vo 手机号，密码等参数
     * @return 注册成功or失败
     */
    @Override
    public ReturnResponse register(UserVO vo) {
        //参数校验
        if (StringUtils.isAnyBlank(vo.getPhone(),vo.getPassword(),vo.getPasswordAgain())){
            return ReturnResponse.failure(ResponseEnum.PARAM_NOT_COMPLETE);
        }
        UserPO po = loginConverter.voToPo(vo);
        String phone = po.getPhone();
        //检查用户（手机号）是否存在
        UserPO checkUser = loginMapper.selectOne(new LambdaQueryWrapper<UserPO>()
                .eq(UserPO::getPhone, phone));
        if (!ObjectUtils.isEmpty(checkUser)){
            return ReturnResponse.failure(ResponseEnum.USER_IS_EXSIT);
        }

        //检查两次密码是否一致
        if (!vo.getPassword().equals(vo.getPasswordAgain())){
            return ReturnResponse.failure(ResponseEnum.PASSWORD_IS_NOEQUELS);
        }
        //验证码校验 单独接口处理

        //密码加密
        String oldPassword = po.getPassword();
        String newPassword = DigestUtils.md5DigestAsHex((salt + oldPassword).getBytes());
        //信息维护入库
        UserPO build = UserPO.builder()
                .phone(phone)
                .password(newPassword)
                .createTime(new Date())
                .updateTime(new Date())
                .build();
        int insert = loginMapper.insert(build);
        if (insert < 0){
            log.info("{}|用户注册失败",phone);
            return ReturnResponse.failure();
        }
        log.info("{}|用户注册成功",phone);
        return ReturnResponse.success();

    }
    /**
     * 邮箱注册 todo 弃用
     * @param vo 邮箱，密码等参数
     * @return 注册成功or失败
     */
//    @Override
//    public ReturnResponse register(UserVO vo) throws UnsupportedEncodingException {
//        String code = vo.getMailCode();
//        //参数校验
//        if (StringUtils.isAnyBlank(vo.getEmail(),vo.getPassword(),vo.getPasswordAgain(),vo.getNickName(),code)){
//            return ReturnResponse.failure(ResponseEnum.PARAM_NOT_COMPLETE);
//        }
//        UserPO po = loginConverter.voToPo(vo);
//        String email = po.getEmail();
//        //检查用户（邮箱）是否存在
//        UserPO checkUser = loginMapper.selectOne(new LambdaQueryWrapper<UserPO>()
//                .eq(UserPO::getEmail, email));
//        if (!ObjectUtils.isEmpty(checkUser)){
//            return ReturnResponse.failure(ResponseEnum.USER_IS_EXSIT);
//        }
//        //检查昵称是否重复
//        String nickName = po.getNickName();
//        UserPO checkName = loginMapper.selectOne(new LambdaQueryWrapper<UserPO>()
//                .eq(UserPO::getNickName, nickName));
//        if (!ObjectUtils.isEmpty(checkName)){
//            return ReturnResponse.failure(ResponseEnum.NICKNAME_IS_EXSIT);
//        }
//        //检查两次密码是否一致
//        if (!vo.getPassword().equals(vo.getPasswordAgain())){
//            return ReturnResponse.failure(ResponseEnum.PASSWORD_IS_NOEQUELS);
//        }
//        //验证码校验
//        Object mailCodeOj = redisService.getString(CommonConstant.MAIL_CODE + email);
//        if (ObjectUtils.isEmpty(mailCodeOj) || !code.equals(mailCodeOj.toString())){
//            return ReturnResponse.failure(ResponseEnum.EMAIL_CODE_ERROR);
//        }else {
//            redisService.deleteRedisByKey(CommonConstant.MAIL_CODE + email);
//        }
//
//        //密码加密
//        String oldPassword = po.getPassword();
//        String newPassword = DigestUtils.md5DigestAsHex((salt + oldPassword).getBytes());
//        //信息维护入库
//        UserPO build = UserPO.builder()
//                .email(email)
//                .password(newPassword)
//                .createTime(new Date())
//                .updateTime(new Date())
//                .nickName(nickName)
//                .build();
//        loginMapper.insert(build);
//        return ReturnResponse.success("注册成功");
//    }


    /**
     * 账号密码登录 1:手机验证码登录，如果不存在即注册
     * 2：密码登录，需用户设置密码
     * @param vo 手机号，密码等参数
     * @return 登录成功or失败
     */
    @Override
    public ReturnResponse login(UserVO vo) {
        String loginType = vo.getLoginType();
        if (StringUtils.isAnyBlank(vo.getPhone(),loginType)){
            return ReturnResponse.failure(ResponseEnum.PARAM_NOT_COMPLETE);
        }
        UserPO po = loginConverter.voToPo(vo);
        String phone = po.getPhone();
        //验证用户是否存在
        UserPO userPo = loginMapper.selectOne(new LambdaQueryWrapper<UserPO>()
                .eq(UserPO::getPhone, phone));
        //密码登录
        if (CommonConstant.LOGIN_PWD.equals(loginType)){
            String password = po.getPassword();
            if (StringUtils.isBlank(password)){
                return ReturnResponse.failure(ResponseEnum.PARAM_NOT_COMPLETE);
            }
            if (ObjectUtils.isEmpty(userPo)){
                return ReturnResponse.failure(ResponseEnum.USER_IS_NOT_EXSIT);
            }
            //验证账号密码
            String newPwd = DigestUtils.md5DigestAsHex((salt + password).getBytes());
            String userPwd = userPo.getPassword();
            if (StringUtils.isBlank(userPwd)){
                return ReturnResponse.failure(ResponseEnum.USER_PWD_ISERROR);
            }
            if (!newPwd.equals(userPwd)){
                return ReturnResponse.failure(ResponseEnum.USER_PWD_ISERROR);
            }

        }else {
            if (ObjectUtils.isEmpty(userPo)){
                //注册
                UserPO build = UserPO.builder().phone(phone).createTime(new Date()).updateTime(new Date()).build();
                int insert = loginMapper.insert(build);
                if (insert<0){
                    return ReturnResponse.failure();
                }
                log.info("{}|用户注册成功",phone);
            }
        }
        log.info("{}|用户登录成功",phone);
        return ReturnResponse.success();

    }
    /**
     * 验证码校验
     * @param vo 验证码、手机号
     * @return 成功or失败
     */
    @Override
    public ReturnResponse checkUser(UserVO vo) {
        String code = vo.getPhoneCode();
        String phone = vo.getPhone();
        if (StringUtils.isAnyBlank(code,phone)){
            return ReturnResponse.failure(ResponseEnum.PARAM_NOT_COMPLETE);
        }
        //验证码校验
        Object phoneCodeOj = redisService.getString(CommonConstant.PHONE_CODE + phone);
        if (ObjectUtils.isEmpty(phoneCodeOj) || !code.equals(phoneCodeOj.toString())){
            return ReturnResponse.failure(ResponseEnum.PHONE_CODE_ERROR);
        }else {
            redisService.deleteRedisByKey(CommonConstant.PHONE_CODE + phone);
            log.info("{}|手机号验证码校验成功",phone);
            return ReturnResponse.success();
        }
    }
}
